package models

import (
	"database/sql"
	"errors"
	"fmt"
	"problemandanswer/datamodel"
	"sync"
	"time"

	"github.com/cht9862/mango/myloger"
	_ "github.com/go-sql-driver/mysql"
)


var (
	User = datamodel.User{}
	Problem = datamodel.Problem{}
	UserRow = datamodel.UserRow{}
	Model MysqlOrm
	Db *sql.DB
	Err error

	logFmt = myloger.NewLog()
	mutex = sync.RWMutex{}
)

func chushihua(){
	mutex.Lock()
	defer mutex.Unlock()
	Problem.Pid = 0
	Problem.Questions = ""
	Problem.Answers = ""
	Problem.Status = ""
	Problem.CreateTime = 0
	Problem.AnswerTime = 0
}

func init(){
	Db, Err = sql.Open("mysql","root:a@199862@tcp(localhost:3306)/problem")
	if Err != nil {
		logFmt.Error("-- > 数据库连接失败")
	}

	Model = MysqlOrm{
		SetUserDescriptors:"修改用户信息",
		AddUserDescriptors:"添加用户信息",
		GetUserDescriptors:"读取校验数用户",
		GetProbDescriptors:"读取问题数据",
		DelProbDescriptors:"删除问题数据",
		SetProbDescriptors:"修改问题数据",
		AddProbDescriptors:"添加校验数用户",
	}
}

// MysqlOrm 调用mysql数据库对象
type MysqlOrm struct {
	SetUserDescriptors string
	AddUserDescriptors string
	GetUserDescriptors string
	AddProbDescriptors string
	GetProbDescriptors string
	DelProbDescriptors string
	SetProbDescriptors string

}

func (m MysqlOrm)GetAllProblems()([]*datamodel.Problem1,error){
	sqlStr := "select * from problemanswer"
	var Problems []*datamodel.Problem1

	rows, err := Db.Query(sqlStr)
	if err != nil {
		fmt.Println("查询失败")
	}
	for rows.Next(){
		var Pid int
		var Questions string
		var Answers string
		var Status string
		var CreateTime int64
		var	AnswerTime int64

		err := rows.Scan(&Pid, &Questions, &Answers, &Status, &CreateTime, &AnswerTime)
		if err != nil {
			break
		}

		// 将CreateTime和AnswerTime 转换成string
		var s1 = time.Unix(CreateTime, 0).Format("2006-01-02 15:04:05")
		var s2 = time.Unix(AnswerTime, 0).Format("2006-01-02 15:04:05")

		var u = &datamodel.Problem1{
			Pid: Pid,
			Questions: Questions,
			Answers: Answers,
			Status: Status,
			CreateTime: s1,
			AnswerTime: s2,
		}

		//5. 将新的结构体存放到Users 这个切片当中
		Problems = append(Problems, u)
	}

	return Problems,nil
}

// AddProblems 使用AddProblems 增加问题信息，需要先向models.Problem 各属性绑定值
func (m MysqlOrm)AddProblems(p datamodel.Problem) error{
	defer chushihua()
	sqlStr := "insert into problemanswer (problem,answer,status,create_time,answer_time) values(?,?,?,?,?)"
	mutex.Lock()
	defer mutex.Unlock()
	insert, err := Db.Prepare(sqlStr)
	defer insert.Close()
	if err != nil {
		str := fmt.Sprintf("-- > 数据库信息填写错误 \n实际错误信息：%v",err)
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}
	_, err = insert.Exec(p.Questions,p.Answers,p.Status,p.CreateTime,p.AnswerTime)
	if err != nil {
		str := fmt.Sprintf("-- > 添加问题失败 \n实际错误信息：%v",err)
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}
	return nil
}

// GetProblems 使用GetProblems 获取问题信息，需要先向models.Problem 各属性绑定值
func (m MysqlOrm)GetProblems(p datamodel.Problem) error{
	defer chushihua()
	mutex.RLock()
	sqlStr := "select * from problemanswer where problem = ?"

	row := Db.QueryRow(sqlStr, p.Questions)
	err := row.Scan(&Problem.Pid,&Problem.Questions,&Problem.Answers,&Problem.Status,&Problem.CreateTime,&Problem.AnswerTime)
	mutex.RUnlock()
	if err != nil {
		str := fmt.Sprintf("-- > 获取问题信息失败 \n实际错误信息：%v",err)
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}

	return nil
}

// DelProblems 使用DelProblems 删除问题信息，需要先向models.Problem 各属性绑定值
func (m MysqlOrm)DelProblems(p datamodel.Problem) error{
	defer chushihua()
	sqlStr := "delete from problemanswer where problem = ?"

	mutex.Lock()
	defer mutex.Unlock()
	insert, err := Db.Prepare(sqlStr)
	if err != nil {
		str := fmt.Sprintf("-- > 数据库信息填写错误 \n实际错误信息：%v",err)
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}
	_, err = insert.Exec(p.Questions)
	if err != nil {
		str := fmt.Sprintf("-- > 删除问题信息失败 \n实际错误信息：%v",err)
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}
	return nil
}

// SetProblems 使用SetProblems 修改问题信息，需要先向models.Problem 各属性绑定值
func (m MysqlOrm)SetProblems(p datamodel.Problem) error{
	defer chushihua()
	mutex.RLock()
	sqlStr := "select * from problemanswer where problem = ?"

	row := Db.QueryRow(sqlStr, p.Questions)
	err := row.Scan(&p.Pid,&p.Questions,&p.Answers,&p.Status,&p.CreateTime,&p.AnswerTime)
	mutex.RUnlock()
	if err != nil {
		str := fmt.Sprintf("-- > 没有找到问题相关数据 \n实际错误信息：%v",err)
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}
	mutex.Lock()
	sqlStr = "UPDATE problemanswer SET problem=?,answer=?,status=?,create_time=?,answer_time=? WHERE name=?"
	_, err = Db.Exec(sqlStr,p.Questions,p.Answers,p.Status,p.CreateTime,p.AnswerTime)
	mutex.Unlock()
	if err != nil {
		str := fmt.Sprintf("-- > 修改问题信息失败 \n实际错误信息：%v",err)
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}
	logFmt.Info("执行完成")
	return nil
}

// SetUser 修改用户信息
func (m MysqlOrm)SetUser(u datamodel.User, oldName string) error {

	mutex.RLock()
	sqlStr := "select * from user where name = ?"
	row := Db.QueryRow(sqlStr, oldName)
	err := row.Scan(&UserRow.Id,&UserRow.Name,&UserRow.Passwd,&UserRow.Phone)
	mutex.RUnlock()
	if err != nil {
		str := fmt.Sprintf("-- > 无法后台获取信息 \n实际错误信息：%v",err)
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}

	mutex.Lock()
	sqlStr = "UPDATE user SET name=?,passwd=?,phone=? WHERE name=?"
	_, err = Db.Exec(sqlStr,u.Name,u.Passwd,u.Phone,oldName)
	mutex.Unlock()
	if err != nil {
		str := fmt.Sprintf("-- > 修改用户信息失败 \n实际错误信息：%v",err)
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}
	return nil
}

// GetUser 校验用户数据
func (m MysqlOrm)GetUser(name, password string) error{

	mutex.RLock()
	sqlStr := "select * from user where name = ?"

	row := Db.QueryRow(sqlStr, name)
	err := row.Scan(&UserRow.Id,&UserRow.Name,&UserRow.Passwd,&UserRow.Phone)
	mutex.RUnlock()
	fmt.Println(UserRow)
	if err != nil {
		str := fmt.Sprintf("-- > 后台获取信息失败 \n实际错误信息：%v",err)
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}
	if UserRow.Name != name {
		str := fmt.Sprintf("-- > 账号密码不正确 ")
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}

	if UserRow.Passwd != password {
		str := fmt.Sprintf("-- > 账号密码不正确 ")
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}
	if len(UserRow.Name) <1 {
		str := fmt.Sprintf("-- > 账号密码不正确 ")
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}
	if len(UserRow.Passwd) <1 {
		str := fmt.Sprintf("-- > 账号密码不正确 ")
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}
	return nil
}

// AddUser 增加 user 数据
func (m MysqlOrm)AddUser(u datamodel.User) error{

	sqlStr := "insert into user (name,passwd,phone) values(?,?,?)"
	mutex.Lock()
	defer mutex.Unlock()

	insert, err := Db.Prepare(sqlStr)
	defer insert.Close()
	if err != nil {
		str := fmt.Sprintf("-- > 数据库信息填写错误 \n实际错误信息：%v",err)
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}
	_, err = insert.Exec(u.Name,u.Passwd,u.Phone)
	if err != nil {
		str := fmt.Sprintf("-- > 添加用户失败 \n实际错误信息：%v",err)
		logFmt.Warning(str)
		err = errors.New(str)
		return err
	}
	return nil
}


